package fr.poy.mygluco.server;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.PropertyUtils;
import org.joda.time.DateMidnight;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import com.google.appengine.api.xmpp.JID;
import com.google.appengine.api.xmpp.Message;
import com.google.appengine.api.xmpp.MessageBuilder;
import com.google.appengine.api.xmpp.SendResponse;
import com.google.appengine.api.xmpp.XMPPService;
import com.google.appengine.api.xmpp.XMPPServiceFactory; 

import fr.poy.mygluco.model.Record;
import fr.poy.mygluco.model.UserProfile;
/**
 * pattern : bg ins1 ins2 event comment
 *  
 * 
 */
@SuppressWarnings("serial")
public class XMPPReceiverServlet extends HttpServlet {
	
	private static Logger log = Logger.getLogger(XMPPReceiverServlet.class.getName());
	
    public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException {
       
    	XMPPService xmpp = XMPPServiceFactory.getXMPPService();
        Message message = xmpp.parseMessage(req);

        String fromJid = message.getFromJid().getId();
        String email = fromJid.substring(0,fromJid.indexOf('/')!=-1?fromJid.indexOf('/'):fromJid.length());
        String body = message.getBody();
        log.finest("message entrant :"+fromJid+":"+body+"---");
        //----traitement message 
        String msgBody = "";
        if(body ==null || body.trim().length()==0)
        	msgBody = getLastRecords(email,24);
        else
        	msgBody = persistrecord(email,body);
        //---reponse  
		log.finest("message sortant :"+msgBody+"---");
        Message msg = new MessageBuilder()
            .withRecipientJids(message.getFromJid())
            .withBody(msgBody)
            .build();
                
        boolean messageSent = false; 
        if (xmpp.getPresence(message.getFromJid()).isAvailable()) {
            SendResponse status = xmpp.sendMessage(msg);
            messageSent = (status.getStatusMap().get(fromJid) == SendResponse.Status.SUCCESS);
        }

        if (!messageSent) {
        	log.finest("message non envoyé : "+fromJid+"---");
            //TODO Send an email message instead...
        }
    }
    
    @SuppressWarnings("unchecked")
	private String getLastRecords(String email,int hours){
    	PersistenceManager pm = AppServiceImpl.getPmf().getPersistenceManager();  
		Query query = pm.newQuery(Record.class);
		query.setOrdering("date DESC, time DESC");
		query.setFilter("date > :min && userEmail == :email"); 
		List<Record> l = (List<Record>) query.execute(new DateTime().minusHours(hours).toDate(),email); 
		StringBuffer sb =new StringBuffer();
		DateTimeFormatter dtf =  DateTimeFormat.shortDateTime();
		for (Record r : l) {
			 sb.append("\n").append(recordToString(r,dtf ));
		}  
		pm.close();
		return sb.toString();
    }
    
    private String persistrecord(String email,String body){
    	
        Integer bg = null;
        String cmt = null;
        String evt = null;
        String flag =null;
        Integer ins1 = null;
        Integer ins2 = null;
        Integer ins3 = null;
        String msgBody = "";
        try { 
			PersistenceManager pm = AppServiceImpl.getPmf().getPersistenceManager(); 
			Query query = pm.newQuery(UserProfile.class);
		    query.setFilter("userEmail == :userEmail");
		    query.setUnique(true);
		    UserProfile ret = (UserProfile)query.execute(email);
			if(ret == null) return "Profile not exist !";
			
			DateMidnight d = new DateMidnight(DateTimeZone.forID(ret.getTimeZone()));
			//bug timezone;decalage 2 heures, appengine stocke en utc (normal !)
	        int t = new DateTime(DateTimeZone.forID(ret.getTimeZone())).getMinuteOfDay() ; 
	        
	        
			Record r = new Record(email,d.getDayOfWeek(),d.toDate(),t, bg,cmt,evt, flag,ins1,ins2,ins3);
	        
		    String[] fields = ret.getXmppPattern().split(" ");
	        log.finest("Fields a parser :"+fields.toString());
	        String[] values = body.split(" ");
			log.finest("values :"+values.toString());
			int p = -1;
			for (String value : values) {
				if(value == null || value.length() == 0) 
					continue;
				
				String field = fields[++p]; 
				if("bg".equals(field) || field.startsWith("ins"))
					PropertyUtils.setSimpleProperty(r, field, Integer.valueOf(value));
				else//string
					PropertyUtils.setSimpleProperty(r, field, value);				
			}
	        	
			pm.makePersistent(r);
			pm.close();
			
			msgBody = "ok:\n"+recordToString(r,DateTimeFormat.shortDateTime().withZone(DateTimeZone.forID(ret.getTimeZone())));
		} catch ( Exception e) {
			log.log(Level.WARNING, "build record", e);
			msgBody = "Erreur : " +e.getMessage();
		}
		return msgBody;
    }
    
    
    
	public String recordToString(Record r,DateTimeFormatter dtf) {
		
		StringBuffer sb = new StringBuffer();
		return sb.append(new DateTime(r.getDate()).toString(dtf)  ).append(" ")
		.append(r.getTime()/60).append(":").append(r.getTime()%60).append(" --> ")
		.append(r.getBg() != null ? "bg=" + r.getBg() + ", " : "")
		.append(r.getIns1() != null ? "ins1=" + r.getIns1() + ", " : "")
		.append(r.getIns2() != null ? "ins2=" + r.getIns2() + ", " : "")
		.append(r.getIns3() != null ? "ins3=" + r.getIns3() + ", " : "")
		.append(r.getFlag() != null ? "flag=" + r.getFlag() + ", " : "")
		.append(r.getEvent() != null ? "event=" + r.getEvent() + ", " : "")
		.append(r.getComment() != null ? "comment=" + r.getComment() : "") 
		.toString();
		 
	}
}